/*****************************************************************************/
/**
 *  @file   DataSet.h
 *  @author Naohisa Sakamoto
 */
/*----------------------------------------------------------------------------
 *
 *  Copyright (c) Visualization Laboratory, Kyoto University.
 *  All rights reserved.
 *  See http://www.viz.media.kyoto-u.ac.jp/kvs/copyright/ for details.
 *
 *  $Id$
 */
/*****************************************************************************/
#pragma once
#include <string>
#include <vector>
#include <kvs/SharedPointer>
#include <kvs/StructuredVolumeObject>
#include <kvs/PointObject>
#include <kvs/TransferFunction>
#include <kvs/Vector3>


class DataSet
{
public:

    struct Range { kvs::Vec3 min; kvs::Vec3 max; bool visible; };
    struct Bounds { std::vector<Range> ranges; };

public:

    typedef kvs::SharedPointer<kvs::StructuredVolumeObject> Volume;
    typedef kvs::SharedPointer<kvs::PointObject> Particle;
    typedef std::vector<Particle> ParticleList;
    typedef std::string Filename;
    typedef std::vector<Filename> FilenameList;

private:

    size_t m_time_step; ///< current time step
    Filename m_loaded_volume_filename; ///< filename of the loaded volume data
    FilenameList m_volume_filenames; ///< list of the filenames of the volume data
    FilenameList m_particle_filenames; ///< list of the filanems of the particle data
    Volume m_volume; ///< volume data for I-PBR
    ParticleList m_particles; ///< list of particle data for O-PBR
    Bounds m_bounds; ///< bounding information of the data
    Range m_range; ///< data range of the volume

public:

    DataSet(): m_time_step(0) {}

    const Volume& volume() const { return m_volume; }
    const Particle& particle() const { return m_particles[m_time_step]; }
    const ParticleList& particles() const { return m_particles; }
    const size_t volumeDataSize() const { return this->volume()->values().byteSize(); }
    const size_t clippedVolumeDataSize() const { kvs::Vec3 r = m_range.max - m_range.min + kvs::Vec3::All(1); return r.x() * r.y() * r.z(); }
    const size_t particleDataSize() const { return this->particle()->numberOfVertices() * 27; }
    const Bounds& bounds() const { return m_bounds; }
    const Range& range() const { return m_range; }
    void setRange( const Range& range ) { m_range = range; }

    size_t timeStep() const { return m_time_step; }
    size_t numberOfTimeSteps() const { return m_particle_filenames.size(); }
    void resetTimeStep() { m_time_step = 0; }
    void incrementTimeStep( const bool loop = false );
    void decrementTimeStep( const bool loop = false );
    void setTimeStep( const size_t time_step );

    bool load( const std::string& volume_dirname, const std::string& particle_dirname );
    bool loadVolume();
    bool loadParticles();
};
